package com.kizuki.thread;

import org.junit.Test;

import java.util.*;
import java.util.concurrent.*;

public class Collection {

    @Test
    public void testConcurrentModificationException(){
        // list set map 类似
        // ConcurrentModificationException 并发修改异常
        List<Integer> list = new ArrayList<>();


        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                list.add(getRandom());
                System.out.println(list);
            }).start();
        }
    }

    @Test
    public void testFixList() throws InterruptedException {
        /**
         * 1. Vector 线程安全
         * 2. Collections.synchronized
         * 3. CopyOnWriteArrayList
         */
//        List<Integer> list = Collections.synchronizedList(new ArrayList<>());
        List<Integer> list = new CopyOnWriteArrayList<>();

        // 减的计时器
        CountDownLatch countDownLatch = new CountDownLatch(20);

        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                list.add(getRandom());
                System.out.println(list + " size = " + list.size());
                countDownLatch.countDown();
            }).start();
        }

        countDownLatch.await();
        System.out.println("最后：" + list + " size = " + list.size());
    }

    @Test
    public void testFixSet(){
        /**
         * 1. Collections.synchronized
         * 2. CopyOnWriteArraySet
         */
//        Set<Integer> set = Collections.synchronizedSet(new HashSet<>());
        Set<Integer> set = new CopyOnWriteArraySet<>();

        for (int i = 1; i <= 20; i++) {
            new Thread(()->{
                set.add(getRandom());
                System.out.println(set);
            }).start();
        }
    }

    @Test
    public void testFixMap() throws InterruptedException {
        /**
         * 1. Collections.synchronized
         * 2. ConcurrentHashMap
         */

        final int num = 5;

//        Map<Integer, Integer> map = Collections.synchronizedMap(new HashMap<>());
        Map<Integer, Integer> map = new ConcurrentHashMap<>();

        // 加的计时器
        CyclicBarrier cyclicBarrier = new CyclicBarrier(num, () -> {
            System.out.println("最后的结果: ");
            System.out.println(map + " size = " + map.size());
        });

        for (int i = 1; i <= num; i++) {
            final int temp = i; // 变量不能放到线程
            new Thread(()->{
                map.put(temp, getRandom());
                System.out.println(Thread.currentThread().getName() + " " + map.size());
                try {
                    cyclicBarrier.await(); // 等待所有任务线程执行完
                    System.out.println(Thread.currentThread().getName() + "等待完成后继续执行任务");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }

            }).start();
        }
        Thread.sleep(2000);
    }


    private Integer getRandom(){
        return 21 + (int)(Math.random() * 1000);
    }

}
